﻿--[[
	Widget name	  	ComboBox
	Author     	 	  	Kurapica
	Create Date	 	   	8/01/2008 23:46
	Change Log
		11/25/2008	Combine List and ComboBox Widgets.
--]]
     
-- ComboBox
do
	-- Check Version
	local version = 1
	if not IGAS:RegisterFile("IGAS.GUI.Widget.ComboBox", version) then
		return
	end
    
    local getmetatable = getmetatable
    local pairs = pairs
    local ipairs = ipairs
    local type = type
    local error = error
    local floor = floor
	local tostring = tostring
	local random = random
    local CreateFrame = IGAS.GUI.CreateFrame
    
	local _GUI = IGAS.GUI
	local _Widget = IGAS.GUI.Widget
    local _BaseFunc = IGAS.GUI.Base.Func
	local _PropertyType = IGAS.GUI.Base.PropertyType
	
    ------------------------------------------------------
	---------------------  List   ----------------------
	------------------------------------------------------
    local List
    
    do        
        local _WidgetName = "List"
        local _Base = "Frame"
    
        local _ComboBoxListContainer = CreateFrame("Frame", "IGASGUI_ListContainer")
        _ComboBoxListContainer.__ShowList = _ComboBoxListContainer.__ShowList or nil
    
        -- Script
        local _FrameBackdrop = {
            bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 16,
            insets = { left = 3, right = 3, top = 3, bottom = 3 }
        }
        
		local function OnTimer(self)
			self.Interval = 0
			self.Parent.Visible = false
		end
        
        local function OnShow(self)
			self:GetChild("Timer").Interval = 2
            
            if _ComboBoxListContainer.__ShowList and _ComboBoxListContainer.__ShowList ~= self then
                _ComboBoxListContainer.__ShowList.Visible = false
            end
            
            _ComboBoxListContainer.__ShowList = self
        end
        
        local function OnHide(self)
            if _ComboBoxListContainer.__ShowList and _ComboBoxListContainer.__ShowList == self then
                _ComboBoxListContainer.__ShowList = nil
            end
			self:GetChild("Timer").Interval = 0
        end
        
		local function OnEnter(self)
			self:GetChild("Timer").Interval = 0
		end
		
		local function OnLeave(self)
			self:GetChild("Timer").Interval = 2
		end
		
		local function Item_OnEnter(self)
			self.Parent:Fire("OnEnter")
		end
		
		local function Item_OnLeave(self)
			self.Parent:Fire("OnLeave")
		end
        
        local function Item_OnClick(self)
            self.Parent:Fire("OnClick", self.Parent.__kList[self.__key], self.Parent.__vList[self.__key])
        end
        
        local function Item_OnDoubleClick(self)
            self.Parent:Fire("OnDoubleClick", self.Parent.__kList[self.__key], self.Parent.__vList[self.__key])
        end
        
        local function OnValueChanged(self)
            local parent = self.Parent
            local iMin, iMax = self:GetMinMaxValues()
            
            for i = 1, parent.__DisplayItemCount do
                parent:GetChild("ListBtn_"..i):GetChild("Text"):SetText(parent.__vList[i + self:GetValue() - 1])
                parent:GetChild("ListBtn_"..i).__key = i + self:GetValue() - 1
            end
        end
        
        local function relayoutFrame(self)
            if not self.__Layout then return end
            
            -- Dropdown List
            local dropCount = self.__DisplayItemCount
            local height = dropCount * 26 + 8
            
            self.Height = height
            
            -- Scroll Bar
            local scrollBar = self:GetChild("ScrollBar")
            
            local i, btn, btnFontString, texture
            
            -- Add Button
            for i = 1, dropCount do
                if not self:GetChild("ListBtn_"..i) then
                    btn = CreateFrame("Button", "ListBtn_"..i, self)
                    btn:ClearAllPoints()
                    btn:SetPoint("LEFT", self, "LEFT", 0, -4)
                    btn:SetPoint("RIGHT", scrollBar, "LEFT", 0, 0)
                    btn:SetPoint("TOP", self, "TOP", 0, (i - 1) * -26)
                    btn:SetHeight(26)
                    btn:SetHighlightTexture("Interface\\BUTTONS\\UI-Common-MouseHilight.blp", "ADD")
                    texture = btn:GetHighlightTexture()
                    texture:SetTexCoord(0.125,0.875,0.125,0.875)
                    btnFontString = CreateFrame("FontString", "Text", btn, "ARTWORK","GameFontNormal")
                    btn:SetFontString(btnFontString)
                    btn:SetText("")
                    btn:Hide()
                    btn.OnClick = Item_OnClick
                    btn.OnDoubleClick = Item_OnDoubleClick
                    btn.OnEnter = Item_OnEnter
                    btn.OnLeave = Item_OnLeave
                end
            end
            
            -- Dispose no use button
            i = dropCount + 1
            while self:GetChild("ListBtn_"..i) do
                self:GetChild("ListBtn_"..i):Dispose()
                i = i + 1
            end
            
            local iStrCount = table.getn(self.__kList or {})
            
            if iStrCount == 0 then
                for i = 1, dropCount do
                    self:GetChild("ListBtn_"..i):Hide()
                end
                self:SetHeight(dropCount * 26 + 8)
                self:GetChild("ScrollBar"):SetMinMaxValues(1, 1)
                self:GetChild("ScrollBar"):Hide()
            elseif dropCount >= iStrCount then
                for i = 1, iStrCount do
                    self:GetChild("ListBtn_"..i):Show()
                    self:GetChild("ListBtn_"..i):GetChild("Text"):SetText(self.__vList[i])
                    self:GetChild("ListBtn_"..i).__key = i
                end
                
                if dropCount > iStrCount then
                    for i = iStrCount +1, dropCount do
                        self:GetChild("ListBtn_"..i):Hide()
                        self:GetChild("ListBtn_"..i):GetChild("Text"):SetText("")
                        self:GetChild("ListBtn_"..i).__key = i
                    end
                end
                
                self:SetHeight(iStrCount * 26 + 8)
                self:GetChild("ScrollBar"):SetMinMaxValues(1, 1)
                self:GetChild("ScrollBar"):Hide()
            else
                for i = 1, dropCount do
                    self:GetChild("ListBtn_"..i):Show()
                    self:GetChild("ListBtn_"..i):GetChild("Text"):SetText(self.__vList[i])
                    self:GetChild("ListBtn_"..i).__key = i
                end
                self:SetHeight(dropCount * 26 + 8)
                self:GetChild("ScrollBar"):SetMinMaxValues(1, iStrCount - dropCount + 1)
                self:GetChild("ScrollBar"):Show()
            end
            
            self:GetChild("ScrollBar"):SetValue(1)
        end
        
        local function OnMouseWheel(self,...)
            local scrollBar = self:GetChild("ScrollBar")
            local iMin, iMax = scrollBar:GetMinMaxValues()
            local iPos = scrollBar:GetValue()
            local step = scrollBar.ValueStep
            local btnC = self.__DisplayItemCount
    
            if arg1 > 0 then
                if IsShiftKeyDown() then
                    scrollBar.Value = iMin
                elseif IsControlKeyDown() then
                    if iPos - btnC > iMin then
                    scrollBar.Value = iPos - btnC
                    else
                    scrollBar.Value = iMin
                    end
                else
                    if iPos - step > iMin then
                    scrollBar.Value = iPos - step
                    else
                    scrollBar.Value = iMin
                    end
                end
            elseif arg1 < 0 then
                if IsShiftKeyDown() then
                    scrollBar.Value = iMax
                elseif IsControlKeyDown() then
                    if iPos + btnC < iMax then
                    scrollBar.Value = iPos + btnC
                    else
                    scrollBar.Value = iMax
                    end
                else
                    if iPos + step < iMax then
                    scrollBar.Value = iPos + step
                    else
                    scrollBar.Value = iMax
                    end
                end
            end
        end
        		
        -- ScriptType
        local _ScriptType = {
            ["OnClick"] = true,
            ["OnDoubleClick"] = true,
        }
		    
        --	FuncProxy
        local _FuncProxy = {
            -- SelectItemByIndex
            ["SelectItemByIndex"] = function(self, index)
                local iStrCount = table.getn(self.__kList or {})
                
                if index > iStrCount then index = iStrCount end
                
                if self.__DisplayItemCount + index > iStrCount then
                    self:GetChild("ScrollBar"):SetValue(iStrCount - self.__DisplayItemCount + 1)
                else
                    self:GetChild("ScrollBar"):SetValue(index)
                end
            end,
            -- SelectItemByText
            ["SelectItemByText"] = function(self, text)
                if self.__vList then
                    for i,k in pairs(self.__vList) do
                        if k == text then
                            self:SelectItemByIndex(i)
                            break
                        end
                    end
                end
            end,
            -- SelectItemByValue
            ["SelectItemByValue"] = function(self, val)
                if self.__kList then
                    for i,k in pairs(self.__kList) do
                        if k == val then
                            self:SelectItemByIndex(i)
                            break
                        end
                    end
                end
            end,
            -- GetTextByValue
            ["GetTextByValue"] = function(self, value)
                if self.__kList then
                    for i,k in pairs(self.__kList) do
                        if k == value then
                            return self.__vList[i]
                        end
                    end
                end
                return nil
            end,
            -- GetValueByText
            ["GetValueByText"] = function(self, text)
                if self.__vList then
                    for i,k in pairs(self.__vList) do
                        if k == text then
                            return self.__kList[i]
                        end
                    end
                end
                return nil
            end,
            -- SetDisplayItemCount
            ["SetDisplayItemCount"] = function(self, cnt)
                if type(cnt) == "number" and cnt > 3 then
                    self.__DisplayItemCount = cnt
                    relayoutFrame(self)
                end
            end,
            -- GetDisplayItemCount
            ["GetDisplayItemCount"] = function(self)
                return self.__DisplayItemCount
            end,
            -- Clear
            ["Clear"] = function(self)
                if self.__kList then
                    for v in pairs(self.__kList) do
                        self.__kList[v] = nil
                    end
                else
                    self.__kList = {}
                end
                if self.__vList then
                    for v in pairs(self.__vList) do
                        self.__vList[v] = nil
                    end
                else
                    self.__vList = {}
                end
                relayoutFrame(self)
            end,
            -- AddItem
            ["AddItem"] = function(self, key, text)
                local idx = 1
                if type(text) == "string" then
                    while self.__kList[idx] ~= nil do
                        idx = idx + 1
                    end
                    self.__kList[idx] = key
                    self.__vList[idx] = text
                end
                relayoutFrame(self)
            end,
            -- SetItem
            ["SetList"] = function(self, list)
                self:Clear()
                self.__Layout = false
                if type(list) == "table" then
                    for k, v in pairs(list) do
                        self:AddItem(k, v)
                    end
                else
                    error("The parameter must be a table")
                end
                self.__Layout = true
                relayoutFrame(self)
            end,
            -- SetItem
            ["SetItem"] = function(self, key, text)
                local idx = 1
                while self.__kList[idx] and self.__kList[idx] ~= key do
                    idx = idx + 1
                end
                self.__kList[idx] = key
                self.__vList[idx] = text
            end,
            -- RemoveItem
            ["RemoveItem"] = function(self, key)
                local idx = 1
                while self.__kList[idx] and self.__kList[idx] ~= key do
                    idx = idx + 1
                end
                if self.__kList[idx] and self.__kList[idx] == key then
                    self.__kList[idx] = nil
                    self.__vList[idx] = nil
                    
                    idx = idx + 1
                    while self.__kList[idx] do
                        self.__kList[idx - 1] = self.__kList[idx]
                        self.__vList[idx - 1] = self.__vList[idx]
                        self.__kList[idx] = nil
                        self.__vList[idx] = nil
                        idx = idx + 1
                    end
                end
                relayoutFrame(self)
            end,
            -- GetScrollStep
            ["GetScrollStep"] = function(self)
                return self:GetChild("ScrollBar").ValueStep
            end,        
            -- SetScrollStep
            ["SetScrollStep"] = function(self, step)
                if step > 0 then
                    self:GetChild("ScrollBar").ValueStep = step
                end
            end,
            -- SuspendLayout
            ["SuspendLayout"] = function(self)
                self.__Layout = false
            end,
            -- ResumeLayout 
            ["ResumeLayout"] = function(self)
                self.__Layout = true
                relayoutFrame(self)
            end,
        }
    
        --	Property
        local _Property = {
            -- DisplayItemCount
            ["DisplayItemCount"] = {
                ["Get"] = function(self)
                    return self:GetDisplayItemCount()
                end,
                ["Set"] = function(self, cnt)
                    self:SetDisplayItemCount(cnt)
                end,
                ["Type"] = _PropertyType.Number,
            },    
            -- ScrollStep
            ["ScrollStep"] = {
                ["Set"] = function(self, step)
                    self:SetScrollStep(step)
                end,
                
                ["Get"] = function(self)
                    return self:GetScrollStep()
                end,
                
                ["Type"] = _PropertyType.Number,
            },
        }
    
        local function _New(parent)	
            local frame = CreateFrame("ScrollFrame", nil, _ComboBoxListContainer)
            
            -- Remove it make it free to set name
            _ComboBoxListContainer:RemoveChild(frame)
        
            frame.FrameStrata = "TOOLTIP"
            frame.MouseWheelEnabled = true
            frame.Visible = false
            frame:ClearAllPoints()
            frame:SetBackdrop(_FrameBackdrop)
            frame:SetBackdropColor(0, 0, 0, 1)
            
            -- Scroll Bar
            local scrollBar = _GUI.CreateFrame("ScrollBar", "ScrollBar", frame)
            scrollBar:Hide()
            
			-- Timer
			local timer = CreateFrame("Timer", "Timer", frame)
			timer.Interval = 0
			timer.OnTimer = OnTimer
            
            frame.__kList = {}
            frame.__vList = {}
            frame.__DisplayItemCount = 6
            frame.__Layout = true
            
            -- Event Handle
            scrollBar.OnValueChanged = OnValueChanged
            scrollBar.OnEnter = Item_OnEnter
            scrollBar.OnLeave = Item_OnLeave
			
            frame:StackScript("OnMouseWheel", OnMouseWheel)
            frame:StackScript("OnShow", OnShow)
            frame:StackScript("OnHide", OnHide)
			frame:StackScript("OnEnter", OnEnter)
			frame:StackScript("OnLeave", OnLeave)
            
            relayoutFrame(frame)

            return frame
        end	
    
        -- Register
        local _WidgetInfo = {
            ["WidgetName"] = _WidgetName,
            ["Base"] = _Base,
            ["FuncProxy"] = _FuncProxy,
            ["Property"] = _Property,
            ["ScriptType"] = _ScriptType,
            ["New"] = _New,
            ["NotChild"] = true,
        }
    
        List = _GUI.NewWidget(_WidgetInfo)
    end

    ------------------------------------------------------
	---------------------   ComboBox   -------------------
	------------------------------------------------------
	local _WidgetName = "ComboBox"
    local _Base = "Frame"

    -- Scripts
	local _FrameBackdrop = {
        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 16,
        insets = { left = 3, right = 3, top = 3, bottom = 3 }
	}
    
    local function clearFocus(self)
        self:ClearFocus()
    end
    
    local function gainFocus(self)
        self:HighlightText()
    end
    
    local function lostFocus(self)
        self:HighlightText(0, 0)
    end
    
    local function OnClick(self)
        self.Parent.__List.Visible = not self.Parent.__List.Visible
    end
    
    local function List_OnClick(self, key, text)
        local parent = self.Parent
        
        if parent.__Value ~= key then
            parent.__Value = key
            parent:GetChild("Text"):SetText(text)
            
            parent:Fire("OnValueChanged", key)
            parent:Fire("OnTextChanged", text)
        end
        self.Visible = false
    end
    
    local function OnHide(self, ...)
        if self.__List.Visible then
            self.__List.Visible = false
        end
    end
    
	local function OnCharComposition(self)	    
	    local value
		local parent = self.Parent
	    local list = parent.__List.__vList or {}
	    local text = self:GetText();
		local textlen = strlen(text);
		local i, name;

		if not text or text == "" then
			return
		end
		
		i, name = next(list)
		while i do
			if strfind(strupper(name), strupper(text), 1, 1) == 1 then
				self:SetText(name);
				if ( self:IsInIMECompositionMode() ) then
					self:HighlightText(textlen - strlen(arg1), -1);
				else
					self:HighlightText(textlen, -1);
				end
				
				value = parent.__List:GetValueByText(name)
            
	            if value then
	                if value ~= parent.__Value then
	                    parent.__Value = value
	                    parent:Fire("OnValueChanged", value)
	                    parent:Fire("OnTextChanged", text)
	                end
	            else
	                parent.__Value = nil
	                parent:Fire("OnTextChanged", text)
	            end
				return;
			end
			i, name = next(list, i)
		end
	end

	local function OnChar(self)
		if ( not self:IsInIMECompositionMode() ) then
			OnCharComposition(self)
		end
	end
	
	local function OnEditFocusGained(self)
		self.Parent:Fire("OnEditFocusGained")
	end
	
	local function OnEditFocusLost(self)
		self.Parent:Fire("OnEditFocusLost")
	end
	
	local function OnEnterPressed(self)
		self.Parent:Fire("OnEnterPressed")
	end
	
	-- ScriptType
	local _ScriptType = {
        ["OnValueChanged"] = true,
        ["OnTextChanged"] = true,
		["OnEditFocusGained"] = true,
		["OnEditFocusLost"] = true,
		["OnEnterPressed"] = true,
	}
	    
	-- FuncProxy
	local _FuncProxy = {
        -- Dispose, release resource
        ["Dispose"] = function(self)
            self.__List:Dispose()
            
            -- Call super's dispose
			self:CallMethod(_Widget[_Base], "Dispose")
        end,
		-- Clear
		["Clear"] = function(self)
            self.__List:Clear()
        end,
        -- AddItem
        ["AddItem"] = function(self, key, text)
            self.__List:AddItem(key, text)
        end,
        -- SetItem
        ["SetItem"] = function(self, key, text)
            self.__List:SetItem(key, text)
        end,
        -- RemoveItem
        ["RemoveItem"] = function(self, key)
            self.__List:RemoveItem(key)
        end,
		-- SetList		
		["SetList"] = function(self, list)
            self.__List:SetList(list)
		end,
		-- GetDisplayItemCount
		["GetDisplayItemCount"] = function(self)
			return self.__List.DisplayItemCount
		end,
		-- SetDisplayItemCount	
		["SetDisplayItemCount"] = function(self, cnt)
			self.__List.DisplayItemCount = cnt
		end,
        -- GetValue
        ["GetValue"] = function(self)
            return self.__Value
        end,
        -- SetValue
        ["SetValue"] = function(self, value)
            local text
			if self.__Value == value then
				return
			end
            if value then
                text = self.__List:GetTextByValue(value)
                if text then
                    self.__Value = value
                    self:GetChild("Text"):SetText(text)
                    
                    self:Fire("OnValueChanged", value)
                    self:Fire("OnTextChanged", text)
                end
			else
				self.__Value = nil
				self:GetChild("Text"):SetText("")
				
				self:Fire("OnValueChanged", nil)
				self:Fire("OnTextChanged", "")
            end
        end,
        -- GetText
        ["GetText"] = function(self)
            return self:GetChild("Text"):GetText()
        end,
        -- SetText
        ["SetText"] = function(self, text)
            if text and type(text) == "string" then
                local value = self.__List:GetValueByText(text)
                
                if value then
                    return self:SetValue(value)
                else
                    self.__Value = nil
                    self:GetChild("Text"):SetText(text)
                    self:Fire("OnTextChanged", text)
                end
            end
        end,
        -- GetScrollStep
        ["GetScrollStep"] = function(self)
            return self.__List:GetScrollStep()
        end,
        -- SetScrollStep
        ["SetScrollStep"] = function(self, step)
            self.__List:SetScrollStep(step)
        end,
        -- GetEditable
		["GetEditable"] = function(self)
			return self:GetChild("Text").MouseEnabled
		end,
        -- SetEditable
		["SetEditable"] = function(self, flag)
			self:GetChild("Text").MouseEnabled = flag
            if not flag then
                self:GetChild("Text").AutoFocus = false
            end
		end,
		-- GetTextObject
		["GetTextObject"] = function(self)
			return self:GetChild("Text")
		end,
        -- SuspendLayout
        ["SuspendLayout"] = function(self)
            self.__List:SuspendLayout()
        end,
        -- ResumeLayout 
        ["ResumeLayout"] = function(self)
            self.__List:ResumeLayout()
        end,
        -- SetAutoFocus
        ["SetAutoFocus"] = function(self, flag)
            if flag and self:GetChild("Text").MouseEnabled then
                self:GetChild("Text").AutoFocus = true
            else
                self:GetChild("Text").AutoFocus = false
            end
        end,
        -- GetAutoFocus
        ["IsAutoFocus"] = function(self)
            return self:GetChild("Text").AutoFocus
        end,
        -- ClearFocus
        ["ClearFocus"] = function(self)
            self:GetChild("Text"):ClearFocus()
        end,
		-- HasFocus
		["HasFocus"] = function(self)
			return self:GetChild("Text"):HasFocus()
		end,
		-- SetFocus
		["SetFocus"] = function(self)
			if self:GetChild("Text").MouseEnabled then
				self:GetChild("Text"):SetFocus()
			end
		end,
    }
    
	-- Property
	local _Property = {
        -- AutoFocus
        ["AutoFocus"] = {
			["Set"] = function(self, state)
				self:SetAutoFocus(state)
			end,
			
			["Get"] = function(self)
				return (self:IsAutoFocus() and true) or false
			end,
			
			["Type"] = _PropertyType.Boolean,
		},
        -- DisplayItemCount
		["DisplayItemCount"] = {
			["Set"] = function(self, list)
				self:SetDisplayItemCount(list)
			end,
			
			["Get"] = function(self)
				return self:GetDisplayItemCount()
			end,
            
			["Type"] = _PropertyType.Number,
		},
        -- ScrollStep
		["ScrollStep"] = {
			["Set"] = function(self, step)
				self:SetScrollStep(step)
			end,
			
			["Get"] = function(self)
				return self:GetScrollStep()
			end,
            
			["Type"] = _PropertyType.Number,
		},
        -- Value
		["Value"] = {
			["Set"] = function(self, value)
				self:SetValue(value)
			end,
			
			["Get"] = function(self)
				return self:GetValue()
			end,
            
			["Type"] = _PropertyType.Object,
		},        
        -- Value
		["Text"] = {
			["Set"] = function(self, text)
				self:SetText(text)
			end,
			
			["Get"] = function(self)
				return self:GetText()
			end,
            
			["Type"] = _PropertyType.String,
		},
        -- Editable
        ["Editable"] = {
			["Set"] = function(self, flag)
				self:SetEditable(flag)
			end,
			
			["Get"] = function(self)
				return (self:GetEditable() and true) or false
			end,
            
			["Type"] = _PropertyType.Boolean,
        },
		-- HideDropDownButton
		["HideDropDownButton"] = {
			["Set"] = function(self, flag)
				self:GetChild("DropdownBtn").Visible = not flag
			end,
			
			["Get"] = function(self)
				return not self:GetChild("DropdownBtn").Visible
			end,
			
			["Type"] = _PropertyType.Boolean,
		},
    }
    
    -- New    
    local _New = function(parent)
        -- EditBox
		local frame = CreateFrame("Frame",nil,parent)
		
        frame:SetWidth(180)
        frame:SetHeight(26)
		frame:SetPoint("CENTER",parent,"CENTER")
		frame:SetBackdrop(_FrameBackdrop)
		frame:SetBackdropColor(0,0,0,1)

        local btnDropdown = CreateFrame("Button", "DropdownBtn", frame)
        btnDropdown:SetWidth(32)
        btnDropdown:SetHeight(32)
        btnDropdown:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 3, 3)
        btnDropdown:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up.blp")
        btnDropdown:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Down.blp")
        btnDropdown:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Disabled.blp")
        btnDropdown:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Highlight.blp", "ADD")
        btnDropdown:SetHitRectInsets(6, 7, 7, 8)

        local edit = CreateFrame("EditBox", "Text", frame)
        edit:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -4)
        edit:SetPoint("RIGHT", btnDropdown, "LEFT", 6, 0)
        edit:SetPoint("BOTTOM", frame, "BOTTOM", 0, 4)
        edit:SetAutoFocus(false)
        edit:SetJustifyH("CENTER")
        edit:SetJustifyV("MIDDLE")
        edit:SetFontObject("GameFontNormalSmall")
       
        local list = CreateFrame(List, "List", frame)
        list:SetPoint("TOPLEFT", frame, "BOTTOMLEFT")
        list:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT")
        frame.__List = list
        
        -- Event Handle
        btnDropdown.OnClick = OnClick
		
        edit.OnTabPressed = clearFocus
        edit.OnEnterPressed = clearFocus
        edit.OnEscapePressed = clearFocus
        edit.OnEditFocusLost = lostFocus
        edit.OnEditFocusGained = gainFocus
		edit.OnCharComposition = OnCharComposition
		edit.OnChar = OnChar
		edit.OnEditFocusGained = OnEditFocusGained
		edit.OnEditFocusLost = OnEditFocusLost
		edit.OnEnterPressed = OnEnterPressed
		
        list.OnClick = List_OnClick
		
		frame:StackScript("OnHide", OnHide)
        
        return frame
    end
	
    local _WidgetInfo = {
        ["WidgetName"] = _WidgetName,
        ["Base"] = _Base,
        ["FuncProxy"] = _FuncProxy,
        ["Property"] = _Property,
        ["ScriptType"] = _ScriptType,
        ["New"] = _New,
        ["List"] = List,
    }
    
    _Widget[_WidgetName] = _GUI.NewWidget(_WidgetInfo)    
end